<?php
namespace App\Http\Controllers\Personal;

use App\Facades\Site;
use App\Http\Controllers\Controller;
use App\Models\Common\CollOption;
use App\Models\Personal\Apm;
use App\Models\Personal\ApmDimscorevo;
use App\Models\Personal\Resume;
use App\Models\Personal\ResumeEducationExp;
use App\Models\Personal\ResumeWorkExp;
use Illuminate\Http\Request;
use App\Models\Common\CollArea;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;


/*
 * 古迪洛克评测对接
 *
 * @author  <82375760@qq.com>
 */
class ApmController extends Controller{
    /**
     * 获取活动列表
     *
     * @param object $activityList //测试的活动列表
     * @param $resumeId 简历id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function apmActivityList($resumeId)
    {
        //分类统计每项活动的测试量
        $posts = Apm::select('activity_id',DB::raw('COUNT(id) as num'))->groupBy('activity_id')->get();
        $activityNum = [];
        //生成以活动id为键，测试量为值的数组
        foreach($posts as $key => $val){
            $activityNum[$val->activity_id] = $val->num + 200;
        }

        //形成：已完成的活动的数组
        $doneArr = [];
        $user = auth()->guard('personal')->user();
        $uid = $user->uid;//当前登录的用户id
        $done = Apm::select('activity_id')->where('uid',$uid)->where('resume_id',$resumeId)->get();
        foreach($done as $key => $value){
            $doneArr[] = $value->activity_id;
        }

        //获取列表的地址
        $url = 'http://gl.normstar.net:8082/ns-napm-web/joinNapm/getActivitys.do';
        //获取列表需要传的key秘钥
        $post_data['key'] = Site::get('apmKey');
        //调用curl方法获取测试项目列表
        $res = $this->getCurl($url, $post_data);
        //对象形式的返回结果
        $res = json_decode($res);

        if($res->succeed){
            //评测的活动列表
            $activityList = $res->data->activityList;
            return view('default.personal.apmActivityList',compact('activityList','resumeId','activityNum','doneArr'));
        }else{
            //输出失败的原因
            echo $res->code;
        }
        die;
    }

    /**
     * 获取测评地址
     *
     * 把活动id，用户信息数组array，传到$url中，返回评测地址$getUrl
     * return $url 评测的地址
     */
    public function apmTestUrl(Request $request)
    {
        $user = auth()->guard('personal')->user();
        $uid = $user->uid;//当前登录的用户id

        $resumeId = $request->resumeId;//简历id
        $activityId = $request->activityId;//选择的活动id

        $resume = Resume::where('uid',$uid)->where('id',$resumeId)->first();

        if(empty($resume)){
            //当简历与当前登录用户不匹配的时候报错，并终止
            abort(404,'不可拿别人的简历评测哦');
            die;
        }

        //有评测结果了的直接跳转结果页面
        $apm = Apm::where('uid',$uid)->where('resume_id',$resumeId)->where('activity_id',$activityId)->first();
        if(!empty($apm)){
            $url = route('apmReport',['resumeId'=> $apm->resume_id, 'activityId'=> $apm->activity_id]);
            //直接跳转到评测结果页面
            Header("HTTP/1.1 303 See Other");
            Header("Location: $url");
            die;
        }
        /**
         * 接口地址,诺姆四达提供**/
        $url = 'http://gl.normstar.net:8082/ns-napm-web/joinNapm/getAccountTestUrl.do';
        //组装测试者的信息
        $post_data = $this->makePostData($resume);
        //公司的key，诺姆四达提供**/
        $post_data['key']       = Site::get('apmKey');
        //活动ID，诺姆四达提供,如果没有提供活动ID，则获取用户的第一个活动
        $post_data['activityId']      = $activityId;
        //加密文
        $idKey = substr(md5($uid.substr($activityId,-3).$resumeId),4,10);
        //测评者唯一ID,必填！用户id and 简历id and 活动id**/
        $post_data['uuid']      = $uid.'__'.$resumeId.'__'.$activityId.'__'.$idKey;

        //获取评测链接
        $res = $this->getCurl($url, $post_data);
        $res = json_decode($res);
        if($res->succeed){
            $data = $res->data;
            //直接跳转到评测页面
            Header("HTTP/1.1 303 See Other");
            Header("Location: $data->url");
            exit;
        }else{
            //输出失败的原因
            echo $res->code;
        }
        die;
    }

    /**
     * 组装测试者的信息
     * @return mixed
     */
    public function makePostData($resume)
    {
        //教育培训经历表查询
        $ResumeEducationExp = ResumeEducationExp::where('uid',$resume->uid)->where('resume_id',$resume->id)->first();
        //工作经历表查询
        $ResumeWorkExp = ResumeWorkExp::where('uid',$resume->uid)->where('resume_id',$resume->id)->orderBy('endtime','desc')->first();
        //姓名,必填！
        $post_data['tname'] = $resume->name;
        //测评者的性别,必填！* 男：man；* 女：woman**/
        $post_data['sex']    = ($resume->sex == '1')?'man':'woman';
        //出生年月,必填！**/
        $birthdayArr = explode('-',$resume->birthday);
        if($birthdayArr['2'] == '00'){
            //把日期未选的定为1号生日
            $birthdayArr['2'] = '01';
            $resume->birthday = implode('-',$birthdayArr);
        }
        $post_data['birthday']    = $resume->birthday;
        //应聘单位,必填！**/
        $post_data['testSite']    = $resume->intentionjobs;
        //身份证,
        //毕业院校,
        $post_data['graduateSchool']    = isset($ResumeEducationExp->school)?$ResumeEducationExp->school:'0';
        //专业,
        $post_data['major']    = isset($ResumeEducationExp->speciality)?$ResumeEducationExp->speciality:'0';
        /**学历,必填！* bachelor(本科),* college(大专),* collegeLT(大专以下),* doctorGE(博士及以上),* master(硕士)**/
        $education = [
            '0'=>'collegeLT',
            '10'=>'collegeLT',
            '20'=>'collegeLT',
            '30'=>'collegeLT',
            '40'=>'college',
            '50'=>'bachelor',
            '60'=>'master',
            '70'=>'doctorGE'
        ];
        $post_data['degree']    = $education[$resume->education];
        //电话,
        $post_data['phone']    = $resume->mobile;
        //目前岗位,必填！
        $post_data['post']    = isset($ResumeWorkExp->post)?$ResumeWorkExp->post:'0';
        //邮箱,必填！
        $post_data['email']    = $resume->email;
        //应聘岗位
        $post_data['candidatePost']    = $resume->intentionjobs;
        //户籍所在地
        $post_data['residenceCityId']    = CollArea::getAreaName($resume->census);
        //政治面貌,member(团员),partyMember(党员),politicsOther(其他),theMasses(群众)
//        $post_data['politics']    = '';
        //所在行业
        $post_data['industryWhere']    = CollOption::getOptionName(isset($ResumeWorkExp->industry)?$ResumeWorkExp->industry:'0','industry');
        return $post_data;
    }

    /**
     * @param string $url
     * @param array $post_data
     * @return bool|mixed
     */
    function getCurl($url = '', $post_data = array()) {
        if (empty($url) || empty($post_data)) {
            return false;
        }
        $o = "";
        foreach ( $post_data as $k => $v )
        {
            $o.= "$k=" . urlencode( $v ). "&" ;
        }
        $post_data = substr($o,0,-1);
        $postUrl = $url;
        $curlPost = $post_data;
        $ch = curl_init();//初始化curl
        curl_setopt($ch, CURLOPT_URL,$postUrl);//抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER, 0);//设置header
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
        $data = curl_exec($ch);//运行curl
        curl_close($ch);
        return $data;
    }

    /*
     * 诺姆四达返回的评测结果
     *
     * 当用户在诺姆四达评测题做完提交后，诺姆四达将发送评测结果到这个地址上
     */
    public function getModule(Request $request)
    {
        //function getTestUrl中把用户id and 简历id and 活动id用'and'链接起来传过去，现在传回来
        $uidAndResumeIdAndActivityId = explode('__',$request->uuid);
        $input = [];
        $input['uid']           = $uidAndResumeIdAndActivityId['0'];//用户id
        $input['resume_id']     = $uidAndResumeIdAndActivityId['1'];//简历id
        $input['activity_id']   = $uidAndResumeIdAndActivityId['2'];//活动id
        $resume = Resume::where('uid',$input['uid'])->where('id',$input['resume_id'])->first();
        //防止恶意注入数据库
        if(empty($resume)){
            //当简历与当前登录用户不匹配的时候报错，并终止
            return response()->json(['succeed'=>false,'code'=>'无此简历']);
            die;
        }
        if(substr(md5($input['uid'].substr($input['activity_id'],-3).$input['resume_id']),4,10) != $uidAndResumeIdAndActivityId['3']){
            return response()->json(['succeed'=>false,'code'=>'校验失败']);
            die;
        }
        $input['total_score']   = $request->totalScore;//总分
        $input['report_url']    = $request->reportUrl;//报告下载地址
        $input['dim_score_vo']  = $request->dimScoreVo;//带有指标结构的所有指标得分，最多四层
        $input['dim_score']     = $request->dimScore;//所有指标的得分
        $input['request_all']   = json_encode($request->all());//整个返回的数据
        $input['identity_card'] = $request->identityCard;//身份证号

        //数据库查找这个测试是不是已经存在，
        $apm_id = Apm::
            where('uid',$uidAndResumeIdAndActivityId['0'])
            ->where('resume_id',$uidAndResumeIdAndActivityId['1'])
            ->where('activity_id',$uidAndResumeIdAndActivityId['2'])
            ->value('id');
        if(isset($apm_id) && $apm_id > 0){
            //一般是不会存在的，但是存在的话，那就不用往下执行了
            return response()->json(['succeed'=>true,'code'=>'已存在']);
        }else{
            //保存返回的数据到apm表，并记录id
            $apm_create = Apm::create($input);
            $apm_id = $apm_create->id;
        }
        /**下面开始处理4级的详细评测结果
         * 循环遍历存入apm_dimscorevo表
         **/
        $dimScoreVo = json_decode('['.$request->dimScoreVo.']');//诺姆四达的数据需要我们加这个操作
        $doDimScoreVo = $this->doDimScoreVo($dimScoreVo,$apm_id,'1','0');

        if($doDimScoreVo){
            //返回"已接收"的成功消息
            return response()->json(['succeed'=>true,'code'=>'成功']);
        }else{
            return response()->json(['succeed'=>false,'code'=>'失败']);
        }
    }

    /*
     * 处理4级的apm_dimscorevo表
     * @return bool
     * */
    public function doDimScoreVo($dimensionScoreList,$apm_id,$dim_class_level,$pid)
    {
        foreach($dimensionScoreList as $key =>$val){
            $dimScoreVos = [];
            $dimScoreVos['apm_id'] = $apm_id;//apm表的id，固定的
            $dimScoreVos['dim_class_level'] = $dim_class_level;//分类等级
            $dimScoreVos['pid'] = $pid;//父类id
            $dimScoreVos['dim_id'] = $val->id;//评测内容在评测平台的id
            $dimScoreVos['dim_name'] = $val->name;//评测项目名称
            $dimScoreVos['dim_score'] = $val->score;//评测分数
            $id = ApmDimscorevo::insertGetId($dimScoreVos);
            if(!($id > 0)){
                //这里出错了的话下面就没法进行了
                die('出错出错');
            }
            //是数组的话，就递归调用本身，
            if(is_array($val->dimensionScoreList) && !empty($val->dimensionScoreList)){
                $this->doDimScoreVo($val->dimensionScoreList,$apm_id,$dim_class_level+1,$id);
            }
        }
        return true;
    }

    /**
     * 评测报表
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     * @param $resumeId 简历id
     */
    public function apmReport(Request $request)
    {
        $user = auth()->guard('personal')->user();
        $uid = $user->uid;//当前登录的用户id;
        $resumeId = $request->resumeId;//简历id
        $activityId = $request->activityId;//选择的活动id
        //当用户评测完后，需根据当前uid、当前resumeId、和点击的activityId去获取评测结果
        $apm = Apm::where('uid',$uid)->where('resume_id',$resumeId)->where('activity_id',$activityId)->first();

        if(empty($apm)){
            //当简历与当前登录用户不匹配的时候报错，并终止
            abort(404,'不可拿别人的简历评测哦');
            die;
        }
        //查找本次测试所有评分
        $ApmDimScoreVo = ApmDimscorevo::where('apm_id',$apm->id)->get();
        //把评测评分 组装成树状数组
        $activityList = $this->makeActivityList($ApmDimScoreVo);
        $resume = Resume::where('uid',$uid)->first();
        return view('default.personal.apmReport',compact('apm', 'activityList', 'resumeId', 'resume'));
    }

    /**
     * 组装成树状数组
     * @param $ApmDimScoreVo 搜索出来的4级的评测结果
     * @param string $pid   每条数据的父类id
     * @return array
     */
    public function makeActivityList($ApmDimScoreVo,$pid='0')
    {
        $activityList = [];
        foreach($ApmDimScoreVo as $key => $val){
            if($val['pid'] == $pid){
                $activityList[$val->id]['con'] = $val;
                //递归组装
                $activityList[$val->id]['son'] = $this->makeActivityList($ApmDimScoreVo,$val->id);
            }
        }
        return $activityList;
    }
}